
#include "chatwindow.h"
#include "ui_chatwindow.h"
#include <QDataStream>
#include <QFileDialog>
#include <QFile>
#include <QMessageBox>
#include <QThread>
#include "client.h"
#include "groupchatwindow.h"
ChatWindow::ChatWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ChatWindow),chatServer(new Server(this))
    //,chatClient(new Client(this))
    ,chatClient(nullptr)
{
    ui->setupUi(this);
    this->setWindowTitle("聊天界面");
    //设置名字
    connect(ui->pushButton_name,&QPushButton::clicked,this,&ChatWindow::setNameButtonClicked);
    //添加好友
    connect(ui->pushButton_friendAdd,&QPushButton::clicked,this,&ChatWindow::addFriendButtonClicked);
    //发送消息
    connect(ui->pushButton_send,&QPushButton::clicked,this,&ChatWindow::sendMessageButtonClicked);
    //连接服务器
    connect(chatServer,&Server::newClientConnected,this,&ChatWindow::handleNewClientConnected);
    //连接客户端
    connect(chatClient,&Client::messageReceived,this,&ChatWindow::handleMessageReceived);
    //连接文件选择按钮的信号
    connect(ui->pushButton_sendFile,&QPushButton::clicked,this,&ChatWindow::sendFileButtonClicked);
    //群聊
    connect(ui->pushButton_group,&QPushButton::clicked,this,&ChatWindow::groupChatWindowButtonClicked);

    userName = "";

    chatServer->listen();


}

ChatWindow::~ChatWindow()
{
    delete ui;
}

QString ChatWindow::getUserName() const
{
    return userName;

}

void ChatWindow::setNameButtonClicked()
{
    userName = ui->lineEdit->text().trimmed();
    if(userName.isEmpty())
    {
        QMessageBox::warning(this,tr("警告"),tr("请输入名字"));
        return;
    }
    //创建或获取客户端对象
    if (!chatClient)
    {
        chatClient = new Client(this);
    }
    chatClient->connectToHost("192.168.1.220",8989,userName);
    ui->lineEdit->setVisible(false);
    ui->lineEdit->clear();
    ui->lineEdit->deleteLater();

    ui->pushButton_name = qobject_cast<QPushButton*>(sender());
    if(ui->pushButton_name)
    {
        ui->pushButton_name->setVisible(false);
        ui->pushButton_name->deleteLater();
    }

    //显示欢迎信息
    ui->chatHistory->append(tr("你好，%1！").arg(userName));


}

void ChatWindow::addFriendButtonClicked()
{
    QString friendName = ui->friendInput->text().trimmed();
    if(friendName.isEmpty())
    {
        QMessageBox::warning(this,tr("警告"),tr("请输入名字"));
    }

    if(friendSockets.contains(friendName))
    {
        QMessageBox::warning(this,tr("警告"),tr("该好友已存在"));
        return;

    }
    if(friendName == userName)
    {
        return;
    }
    Client *client = new Client(this);
    connect(client,&Client::messageReceived,this,&ChatWindow::handleMessageReceived);
    client->connectToHost("192.168.1.220",8989,userName);

    ui->friendsList->addItem(friendName);
    friendSockets.insert(friendName,nullptr);

    ui->friendInput->clear();
}


void ChatWindow::sendMessageButtonClicked()
{
    //获取当前选中的好友
    QListWidgetItem *item = ui->friendsList->currentItem();
    if(!item)
    {
        QMessageBox::warning(this,tr("Waring"),tr("请选择一个好友发送消息！"));
        return;
    }

    QString friendName = item->text();
    QTcpSocket *socket = friendSockets.value(friendName);
    if(!socket)
    {
        QMessageBox::warning(this,tr("Waring"),tr("没有连接到 %1").arg(friendName));
    }

    //获取要发送的信息
    QString message = ui->messageInput->text();
    if(message.isEmpty())
    {
        QMessageBox::warning(this,tr("Warning"),"请发送一个消息！");
        return;
    }
    //显示消息
    ui->chatHistory->append(tr("我：%1").arg(message));
    ui->messageInput->clear();

    //发送消息
    socket->write(message.toUtf8());
}

void ChatWindow::sendFileButtonClicked()
{
    //打开文件对话框让用户选择文件
    QString fileName = QFileDialog::getOpenFileName(this,tr("选择文件"), "",tr("所有文件 (*)"));

    if(!fileName.isEmpty())
    {
        QListWidgetItem *it = ui->friendsList->currentItem();
        if(!it)
        {
            QMessageBox::warning(this,tr("警告"),tr("请选择一个好友发送文件！"));
            return;
        }

        QString friendName = it->text();
        QTcpSocket *socket = friendSockets.value(friendName);
        if(!socket)
        {
            QMessageBox::warning(this,tr("警告"),tr("没有连接到 %1").arg(friendName));
            return;
        }

        //读取文件内容
        QFile file(fileName);
        if(!file.open(QIODevice::ReadOnly))
        {
            QMessageBox::critical(this,tr("错误"),tr("无法打开文件 %1").arg(fileName));
        }

        //发送文件名
        QByteArray fileNameData = fileName.toUtf8();
        socket->write("FILE:");
        socket->write(fileNameData);
        socket->write(":");

        //发送文件大小
        qint64 fileSize = file.size();
        QDataStream out(socket);
        out << fileSize;

        //发送文件内容
        while(!file.atEnd())
        {
            QByteArray block = file.read(1024);//每次读取1024字节
            socket->write(block);
            socket->waitForBytesWritten();
        }

        file.close();
        socket->flush();

        //显示发送信息
        ui->chatHistory->append(tr("%1 给 %2 发送了文件").arg(fileName).arg(friendName));
    }

}

void ChatWindow::handleNewClientConnected(QTcpSocket *client)
{
    QString friendName = client->property("username").toString();
    if(friendName.isEmpty())
    {
        friendName = "newFriend";
    }

    friendSockets.insert(friendName,client);
    ui->friendsList->addItem(friendName);
    //连接客户端的信号
    connect(client,&QTcpSocket::readyRead,this,&ChatWindow::handleMessageReceived);

    connect(client,&QTcpSocket::disconnected,this,[this,client](){
        QString friendName = client->property("username").toString();
        friendSockets.remove(friendName);
        qDebug() << "客户端断开：" << friendName;
    });

}

void ChatWindow::handleMessageReceived()
{
    QTcpSocket *client = qobject_cast<QTcpSocket*>(sender());
    if(!client)
    {
        qDebug() << "无效的发送";
        return;
    }

    QByteArray data = client->readAll();
    QString message = QString::fromUtf8(data);
    //显示接收的消息
    QString username = client->property("username").toString();
    ui->chatHistory->append(tr("%1：%2").arg(username).arg(message));
}

void ChatWindow::groupChatWindowButtonClicked()
{
    GroupChatWindow *groupChatWindow = new GroupChatWindow(this);
    groupChatWindow->show();
    this->hide();

}

